/**
 * count组件;
 */
import { Component, Input, forwardRef, OnChanges, SimpleChanges } from '@angular/core';
// import { ControlValueAccessor } from '../../directives/control_value_accessor';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, Validator,
  AbstractControl, ValidatorFn, ValidationErrors, FormControl
} from '@angular/forms';

// 1. 创建 EXE_COUNTER_VALUE_ACCESSOR
export const EXE_COUNTER_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => CounterComponent),
  multi: true
};

// 4. 注册自定义验证器 -- Validator
export const EXE_COUNTER_VALIDATOR = {
  provide: NG_VALIDATORS,
  // useValue: validateCounterRange,
  useExisting: forwardRef(() => CounterComponent),
  multi: true
};

// 2. 定义验证函数 -- 新增一个 createCounterRangeValidator() 工厂函数，
    // 用于根据设置的最大值 (maxValue) 和最小值 (minValue) 动态的创建 validateCounterRange() 函数;
export function createCounterRangeValidator(maxValue: number, minValue: number) {
  return (control: AbstractControl): ValidationErrors => {
    return (control.value > +maxValue || control.value < +minValue) ?
      { 'rangeError': { current: control.value, max: maxValue, min: minValue }} : null;
  };
}

// 3. 要实现指令的自定义验证功能，我们需要实现 Validator 接口：
export interface Validator {
  validate(c: AbstractControl): ValidationErrors | null;
  registerOnValidatorChange?(fn: () => void): void;
}


@Component({
  selector: 'app-counter',
  template: `
    <div>
      <p>当前值：{{count}}</p>
      <button (click)="increment()">++</button>
      <button (click)="decrement()">--</button>
    </div>
  `,
  providers: [EXE_COUNTER_VALUE_ACCESSOR, EXE_COUNTER_VALIDATOR]
})
export class CounterComponent implements ControlValueAccessor, Validator, OnChanges {

  @Input() _count: number = 0;

  private _validator: ValidatorFn;
  private _onChange: () => void;

  @Input() counterRangeMin: number; // 设置数据有效范围的最大值

  @Input() counterRangeMax: number; // 设置数据有效范围的最小值

  // 监听输入属性变化，调用内部的_createValidator()方法，创建RangeValidator
  ngOnChanges(changes: SimpleChanges): void {
    if ('counterRangeMin' in changes || 'counterRangeMax' in changes) {
      this._createValidator();
    }
  }

  // 动态创建RangeValidator
  private _createValidator(): void {
    this._validator = createCounterRangeValidator(this.counterRangeMax, this.counterRangeMin);
  }

  // 执行控件验证 -- 实现 Validator 接口
  validate(c: AbstractControl): ValidationErrors | null {
    return this.counterRangeMin == null || this.counterRangeMax == null ?
      null : this._validator(c);
  }

  get count() {
    return this._count;
  }

  set count(value: number) {
    this._count = value;
    this.propagateChange(this._count);
  }

  propagateChange = (_: any) => { };

  writeValue(value: any) {
    if (value !== undefined) {
      this.count = value;
    }
  }

  registerOnChange(fn: any) {
    this.propagateChange = fn;
  }

  registerOnTouched(fn: any) { }

  increment() {
    this.count ++;
  }

  decrement() {
    this.count--;
  }
}
